--
-- Author: shineflag
-- Date: 2017-02-20 19:11:01
--
local skynet = require "skynet"
local cts = require("constants")
local log = require "log"
local proto = require("json_proto")
local json = require("json")
local cts = require("constants")
local socket = require "skynet.socket"
local sconf = require("server_conf")
local cluster = require "skynet.cluster"

local uncrypt = true  --协议是否不加密
local gate 

local TAG = "ADMIN"
local SOCKET = {}   --socket事件
local CLIENT = {}   --client通过socket发过来的命令
local CMD = {}      --其它

local robot_num = 0 --上报机器人的在线在玩
local report_robot_time = 0 --上报机器人的时间
local report_timeout = 70

local function send_msg(fd, msg)
	socket.write(fd,msg)
end

--获取上报的机器人数量
local function get_report_robot_num()
	local now = os.time()
	if now - report_robot_time > report_timeout then 
		return 0 
	else
		return robot_num
	end
end

--获取投注的 地址
local function get_dice_proxy()
	local cluster_name = "cluster_dice"
	local dice = cluster.query(cluster_name, "happydice")
	local dice_proxy = cluster.proxy(cluster_name, dice)
	log.d(TAG, "dice_proxy:%s proxy:%s", dice,dice_proxy)
	return dice_proxy
end 



----[[  socket消息处理
function SOCKET.open(fd, addr)
	log.d(TAG, "New client from %s fd[%d]" , addr,fd)
	skynet.call(gate, "lua", "accept", fd)
end

function SOCKET.close(fd)
	log.d(TAG, "New client from %s" , addr)
end

function SOCKET.error(fd, msg)
    log.d(TAG,"socket error ",fd)
end

function SOCKET.warning(fd, size)
    log.d(TAG,"socket warning ",fd)
end

function SOCKET.data(fd, msg)
	local pkg = proto.unpack_body(msg,uncrypt)

	log.d(TAG,"sfd[%d] recv pkg[%s]",fd,json.encode(pkg))

	local model, cmd = pkg.cmd:match("([^.]+).([^.]+)")

	if model == "admin" then
		local f = CLIENT[cmd]
		if f then 
			f(fd, pkg)
		else
			log.e(TAG,"Unkow model[%s] command[%s]",model,cmd)
		end
	else
		local service
		if model == "alloc" then 
			service = skynet.uniqueservice "cash/alloc"
		elseif model == "mtt" then
			service = skynet.uniqueservice "match/mtt"
		elseif model == "happydice" then
			service = get_dice_proxy()
		else
		 	service = skynet.uniqueservice(model)
		end
		
		if service then
			local rpkg = skynet.call(service, "lua", cmd,pkg.req, uncrypt)
			send_msg(fd, rpkg)
		else
			log.e(TAG,"Unkow model[%s] command[%s]",model,cmd)
		end
	end 

end

--]]



----[[ php调的

--获取现金场的在玩
function CLIENT.cashplayers(fd, pkg)
	local cash = skynet.uniqueservice "alloc"
	local result = skynet.call(cash, "lua", "get_players_info",pkg.req.lv or 0)
	local rpkg = proto.create_resp("admin.cashplayers",{ret=200,info=result}, uncrypt)
	send_msg(fd, rpkg)
end

function CLIENT.onlineinfo(fd, pkg)
	local cash = skynet.uniqueservice "cash/alloc"
	local cash_players = skynet.call(cash, "lua", "get_players_num")

	local sng = skynet.uniqueservice "match/sng"
	local sng_players = skynet.call(sng, "lua", "get_players_num")


	local custom = skynet.uniqueservice "custom/custom"
	local custom_player = skynet.call(custom, "lua", "get_players_num")

	local tplayers = cash_players + sng_players + custom_player

	local user_mgr = skynet.uniqueservice "user_mgr"    --用户中心
	local online_num = skynet.call(user_mgr, "lua", "get_online")

	local robot_num = get_report_robot_num()
	local rpkg = proto.create_resp("admin.onlineinfo",{ret=200,online=online_num, onplay=tplayers, robot=robot_num}, uncrypt)
	send_msg(fd, rpkg)
	log.d(TAG,"onlineinfo robot[%d] cash[%d] sng[%d] custom[%d] tplayer[%d] online[%d]",robot_num,cash_players,sng_players, custom_player, tplayers,online_num)

end

--发送广播
function CLIENT.broadcast(fd, pkg)
	local msgbox = skynet.uniqueservice "msgbox"
	local data = pkg.req 
	log.d(TAG,"broadcast[%s]",json.encode(data))
	local result = skynet.call(msgbox, "lua", "admin_broad",
		data.sender, data.mtype, data.title, data.content)
	local rpkg = proto.create_resp("admin.broadcast",{ret=200}, uncrypt)
	send_msg(fd, rpkg)
end

--发送公告
function CLIENT.pushnotice(fd, pkg)
	local msgbox = skynet.uniqueservice "msgbox"
	local data = pkg.req 
	log.d(TAG,"pushnotice[%s]",json.encode(data))
	local result = skynet.call(msgbox, "lua", "pushnotice",
		data.title, data.content)
	local rpkg = proto.create_resp("admin.pushnotice",{ret=200}, uncrypt)
	send_msg(fd, rpkg)
end

--向单个在线用户推送消息
function CLIENT.pushmsg(fd, pkg)
	local msgbox = skynet.uniqueservice "msgbox"
	local data = pkg.req 
	log.d(TAG,"pushmsg[%s]",json.encode(data))
	local result = skynet.call(msgbox, "lua", "pushmsg",data)
	local rpkg = proto.create_resp("admin.pushmsg",{ret=200}, uncrypt)
	send_msg(fd, rpkg)
end

--发送公告
function CLIENT.clearnotice(fd, pkg)
	local msgbox = skynet.uniqueservice "msgbox"
	log.d(TAG,"clearnotice")
	local result = skynet.call(msgbox, "lua", "clearnotice")
	local rpkg = proto.create_resp("admin.clearnotice",{ret=200}, uncrypt)
	send_msg(fd, rpkg)
end

--更改用户金币
function CLIENT.updatemoney(fd, pkg)
	local mdata = skynet.uniqueservice "mdata"
	local data = pkg.req 
	log.d(TAG,"updatemoney[%s]",json.encode(data))
	local result = skynet.call(mdata, "lua", "changemoney",
		data.mid, data.change, data.rz)

	local rpkg 
	if not result then 
		rpkg = proto.create_resp("admin.updatemoney",{ret=-101,mid=data.mid}, uncrypt)
	else
		rpkg = proto.create_resp("admin.updatemoney",{ret=200,mid=data.mid,left=result}, uncrypt)
	end
	send_msg(fd, rpkg)
end

--更改用户积分
function CLIENT.updatescore(fd, pkg)
	--[[ 刚注册的用户加会失败
	local vip = skynet.uniqueservice "vip"
	local data = pkg.req 
	log.d(TAG,"updatescore[%s]",json.encode(data))
	local result = skynet.call(vip, "lua", "change_score",
		data.mid, data.change, data.rz)
	--]]

	local mdata = skynet.uniqueservice "mdata"
	local data = pkg.req 
	log.d(TAG,"updatescore[%s]",json.encode(data))
	local result = skynet.call(mdata, "lua", "changescore",
		data.mid, data.change, data.rz)

	local rpkg 
	if not result then 
		rpkg = proto.create_resp("admin.updatescore",{ret=-101,mid=data.mid}, uncrypt)
	else
		rpkg = proto.create_resp("admin.updatescore",{ret=200,mid=data.mid,left=result}, uncrypt)
	end
	send_msg(fd, rpkg)
end

--更改用户投注币
function CLIENT.updategold(fd, pkg)
	local mdata = skynet.uniqueservice "mdata"
	local data = pkg.req 
	log.d(TAG,"updategold[%s]",json.encode(data))
	local result = skynet.call(mdata, "lua", "changegold",
		data.mid, data.change, data.rz)

	local rpkg 
	if not result then 
		rpkg = proto.create_resp("admin.updategold",{ret=-101,mid=data.mid}, uncrypt)
	else
		rpkg = proto.create_resp("admin.updategold",{ret=200,mid=data.mid,left=result}, uncrypt)
	end
	send_msg(fd, rpkg)
end

--获取用户的游戏数据
function CLIENT.getginfo(fd, pkg)

	local data = pkg.req
	log.d(TAG,"getuserginfo[%s]",json.encode(data))
	local mdata_proxy = skynet.uniqueservice "mdata"
	local ok, res = skynet.call(mdata_proxy, "lua", "getall", data.mid)
	local resp = {ret=200,mid=data.mid, money = 0, score=0, gold=0}
	if ok then 
		resp.money = res.money 
		resp.score = res.score
		resp.gold = res.gold
	else
		ret = -101
	end


	local rpkg = proto.create_resp("admin.getginfo",resp, uncrypt)
	send_msg(fd, rpkg)
end


--用户消耗积分 兑换商品
function CLIENT.exchange(fd, pkg)

	local data = pkg.req
	log.d(TAG,"exchange[%s]",json.encode(data))
	local vinfo = skynet.uniqueservice "vip"
	local left = skynet.call(vinfo, "lua", "exchange", data.mid, data.reuire_lv, data.score, data.rz)
	local resp = {ret=200,mid=data.mid}
	if left < 0 then 
		resp.ret = left  -- -101:积分不足  -102:vip等级不足
	else
		resp.left = left 
	end

	local rpkg = proto.create_resp("admin.exchange",resp, uncrypt)
	send_msg(fd, rpkg)
end

--获取用户真实金币 财富用于判断是否破产
function CLIENT.realmoney(fd, pkg)

	local data = pkg.req
	log.d(TAG,"realmoney[%s]",json.encode(data))
	local mdata_proxy = skynet.uniqueservice "mdata"
	local coins = skynet.call(mdata_proxy, "lua", "getcoins", data.mid)
	local cur_coin = 0
	if coins and next(coins) then 
		for k,v in pairs(coins) do 
			local lv, tid = k:match("([^.]+)_([^.]+)")
			lv = tonumber(lv)
			if lv < 1000 then 
				cur_coin = cur_coin + tonumber(v)
			end
		end
	end
	local cur_money = skynet.call(mdata_proxy, "lua", "getmoney", data.mid) or 0
	local realmoney = cur_money + cur_coin 

	local resp = {ret=200,mid=data.mid, realmoney = realmoney}
	local rpkg = proto.create_resp("admin.realmoney",resp, uncrypt)
	send_msg(fd, rpkg)
end

 --获取用户的基础信息
function CLIENT.getubinfo(fd, pkg)

	local data = pkg.req
	log.d(TAG,"getubinfo[%s]",json.encode(data))
	local ubinfo = skynet.uniqueservice("uinfo")
	local ok,ret = skynet.call(ubinfo, "lua", "getuinfo", data.mid)
	local resp = {ret=200,info={mid=data.mid}}
	if ok then 
		for k, v in pairs(ret) do 
			resp.info[k] = v
		end
	else
		resp.ret = -101
	end


	local rpkg = proto.create_resp("admin.getubinfo",resp, uncrypt)
	send_msg(fd, rpkg)
end

--]]




----[[ 其它服务调的接口
function CMD.report_robot_num(num)
	report_robot_time = os.time() 
	robot_num = num 
	log.d(TAG,"report robot[%d]",num)
end



--初始化 call by main
function CMD.init()
	local admin_port = skynet.getenv("admin_port")
	gate = skynet.newservice("gate")
	skynet.call(gate, "lua", "open", {
			port = sconf["admin_port"],
			maxclient = 1000,
			nodelay = true,
		})
end
--]]

skynet.start(function ( ... )

	skynet.dispatch("lua", function(_, session, cmd, subcmd, ...)
        if cmd == "socket" then
            local f = SOCKET[subcmd]
            f(...)
            -- socket api don't need return
        else
            local f = CMD[cmd]
            assert(f, cmd)
            if session == 0 then
                f(subcmd, ...)
            else
                skynet.ret(skynet.pack(f(subcmd, ...)))
            end
        end
    end)

end)